跳到主要内容

崩溃日志收集与上报体系怎么搭建?

考察点​

  • 日志分级、落盘轮转
  • minidump 崩溃上报与符号化

参考答案​

1. 体系全景​

三层日志:
1. JS 层日志(electron-log)→ 本地文件轮转 + 按需上报
2. 崩溃转储(crashReporter minidump)→ 自动上报 + 符号化
3. 渲染进程日志 → IPC 汇集到主进程统一落盘

2. JS 层日志​

(1)electron-log 配置

const log = require('electron-log/main');

// 初始化(主进程)
log.initialize();

// 分级与格式
log.transports.file.level = 'info';
log.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] [{processType}] {text}';

// 轮转策略:按大小切分,保留最近 N 个
log.transports.file.maxSize = 10 * 1024 * 1024; // 单文件 10MB
log.transports.file.archiveLogFn = (oldLogFile) => {
// 归档压缩,最多保留 5 个历史文件
};

(2)渲染进程日志汇集

// 渲染进程的 console 自动转发到主进程(electron-log 能力)
log.initialize({ preload: true });

// 或手动:preload 桥接 log API,渲染侧调 api.log.info(...)

所有进程日志汇聚到同一文件(带 processType 区分),排查时不用东拼西凑。

(3)分级与采样

  • 线上默认 info 级;debug/verbose 通过远程开关(配置下发)针对问题设备开启
  • 高频日志采样(如心跳日志 1/100 采样),避免日志爆炸

3. 崩溃转储(minidump)​

const { crashReporter } = require('electron');

crashReporter.start({
productName: 'MyAgent',
companyName: 'MyCompany',
submitURL: 'https://crash.example.com/api/minidump',
uploadToServer: true,
ignoreSystemCrashHandler: false,
// 附加业务字段,定位问题现场
extra: {
version: app.getVersion(),
channel: getUpdateChannel(),
},
});
  • 采集的是进程级崩溃(段错误、原生层 crash),JS try/catch 抓不到的那类
  • 产物是 minidump 文件(.dmp),需要 breakpad 符号表做符号化才能看到可读的堆栈
  • 自建服务端可用 [mini-breakpad-server] 或直接把符号和 dmp 传 Sentry

4. 崩溃堆栈符号化​

发布时:从构建产物提取符号文件(.sym/.pdb/dSYM)→ 归档到符号服务器
收到 dmp:符号化工具(minidump_stackwalk / Sentry)+ 符号文件 → 可读调用栈

要点:

  • 每个发布版本的符号必须归档,丢符号 = 该版本崩溃无法分析
  • JS 层错误还要 sourcemap 还原(构建时上传 sourcemap 到 Sentry,注意别公开分发)

5. 上报策略​

  • 崩溃即报:minidump 由 crashReporter 自动上传
  • 日志按需拉取:全量日志太大,服务端下发"日志采集指令"→ agent 打包最近 N 天日志脱敏上传(用户隐私敏感字段要脱敏:路径中的用户名、token 等)
  • 问题反馈入口:托盘菜单"问题反馈"一键打包日志+系统信息,用户授权后上传

6. 指标体系​

按版本聚合:

  • 崩溃率 = 崩溃设备数 / 活跃设备数(灰度发布的关键决策指标)
  • 崩溃 TopN 堆栈聚类(同堆栈归并)
  • JS 错误率、未捕获 rejection 数

新崩溃堆栈出现 → 告警 → 关联发布批次 → 决定停止放量或热修。

7. 常见坑​

  1. crashReporter 要尽早 start(主进程入口),否则启动期崩溃采不到
  2. 每个进程类型都要启动(主进程 start 后渲染进程自动继承配置,但 utility process 要单独处理)
  3. 日志文件写入要异步队列化,崩溃瞬间同步写可能丢日志
  4. Windows 上 minidump 上传需要崩溃后下次启动才发(崩溃时进程已死)——启动时检查 pending 崩溃并上报

面试话术​

体系三层:electron-log 分级轮转做 JS 日志(渲染进程汇集到主进程统一落盘);crashReporter 做 minidump 崩溃上报,关键是每版本符号归档 + 符号化;上报策略分崩溃即报与日志按需拉取(脱敏后)。最终形成按版本聚合的崩溃率指标,直接驱动灰度放量决策。

常见追问​

  • 用户没网时崩溃日志怎么办? 本地暂存,联网后补报;minidump 本身就保存在 crashes 目录。
  • 怎么定位"没崩溃但功能异常"的问题? 远程日志开关 + 关键链路结构化埋点(traceId 串联一次操作的全链路日志)。